1 ========================================================================
2 CONSOLE APPLICATION : VBNamedPipeClient Project Overview
3 ========================================================================
5 /////////////////////////////////////////////////////////////////////////////
8 Named pipe is a mechanism for one-way or duplex inter-process communication
9 between the pipe server and one or more pipe clients in the local machine or
10 across the computers in the intranet:
13 Client (GENERIC_WRITE) ---> Server (GENERIC_READ)
16 Client (GENERIC_READ) <--- Server (GENERIC_WRITE)
19 Client (GENERIC_READ or GENERIC_WRITE, or both) <-->
20 Server (GENERIC_READ and GENERIC_WRITE)
22 This code sample demonstrate two methods to use named pipe in Visual C#.
24 1. Use the System.IO.Pipes namespace
26 The System.IO.Pipes namespace contains types that provide a means for
27 interprocess communication through anonymous and/or named pipes.
28 http://msdn.microsoft.com/en-us/library/system.io.pipes.aspx
29 These classes make the programming of named pipe in .NET much easier and
30 safer than P/Invoking native APIs directly. However, the System.IO.Pipes
31 namespace is not available before .NET Framework 3.5. So, if you are
32 programming against .NET Framework 2.0, you have to P/Invoke native APIs
35 The sample code in SystemIONamedPipeClient.Run() uses the
36 Systen.IO.Pipes.NamedPipeClientStream class to connect to the named pipe
37 "\\.\pipe\SamplePipe" to perform message-based duplex communication.
38 The client then writes a message to the pipe and receives the response from the
41 2. P/Invoke the native APIs related to named pipe operations.
43 The .NET interop services make it possible to call native APIs related to
44 named pipe operations from .NET. The sample code in
45 NativeNamedPipeClient.Run() demonstrates calling CreateFile to connect to
46 the named pipe "\\.\pipe\SamplePipe" with the GENERIC_READ and
47 GENERIC_WRITE accesses, and calling WriteFile and ReadFile to write a
48 message to the pipe and receive the response from the pipe server. Please
49 note that if you are programming against .NET Framework 3.5 or any newer
50 releases of .NET Framework, it is safer and easier to use the types in the
51 System.IO.Pipes namespace to operate named pipes.
54 /////////////////////////////////////////////////////////////////////////////
57 The following steps walk through a demonstration of the named pipe sample.
59 Step1. After you successfully build the VBNamedPipeClient and
60 VBNamedPipeServer sample projects in Visual Studio 2008, you will get the
61 applications: VBNamedPipeClient.exe and VBNamedPipeServer.exe.
63 Step2. Run VBNamedPipeServer.exe in a command prompt to start up the server
64 end of the named pipe. If the command is "VBNamedPipeServer.exe", the pipe
65 server is created by the types in the System.IO.Pipes namespace. If the
66 command is "VBNamedPipeServer.exe -native", the pipe server is created by
67 P/Invoking the native APIs related to named pipe operations. In both cases,
68 the application outputs the following information in the command prompt if
69 the pipe is created successfully.
72 The named pipe (\\.\pipe\SamplePipe) is created.
73 Waiting for the client's connection...
75 Step3. Run VBNamedPipeClient.exe in another command prompt to start up the
76 client end of the named pipe. If the command is "VBNamedPipeClient.exe", the
77 client connects to the pipe by using the types in the System.IO.Pipes
78 namespace. If the command is "VBNamedPipeClient.exe -native", the client
79 connects to the pipe by P/Invoking the native APIs related to named pipe
80 operations. In both cases, the application should output the message below
81 in the command prompt when the client successfully connects to the named pipe.
84 The named pipe (\\.\pipe\SamplePipe) is connected.
86 In the meantime, the server application outputs this message to indicate that
87 the pipe is connected by a client.
92 Step4. The client attempts to write a message to the named pipe. You will see
93 the message below in the commond prompt running the client application.
96 Send 56 bytes to server: "Default request from client"
98 When the server application reads the message from the client, it prints:
101 Receive 56 bytes from client: "Default request from client"
103 Next, the server writes a response to the pipe.
106 Send 58 bytes to client: "Default response from server"
108 And the client receives the response:
111 Receive 58 bytes from server: "Default response from server"
113 The connection is disconnected and the pipe is closed after that.
116 /////////////////////////////////////////////////////////////////////////////
118 (The relationship between the current sample and the rest samples in
119 Microsoft All-In-One Code Framework http://1code.codeplex.com)
121 VBNamedPipeClient -> CSNamedPipeServer/VBNamedPipeServer/CppNamedPipeServer
122 VBNamedPipeServer is the client end of the named pipe. CSNamedPipeServer,
123 VBNamedPipeServer and CppNamedPipeServer can be the server ends that create
126 VBNamedPipeClient - CSNamedPipeClient - CppNamedPipeClient
127 VBNamedPipeClient, CSNamedPipeClient and CppNamedPipeServer are the same
128 named pipe client ends written in three different programming languages.
131 /////////////////////////////////////////////////////////////////////////////
134 A. Named pipe client by using the System.IO.Pipes namespace.
135 (SystemIONamedPipeClient.Run())
137 1. Create a NamedPipeClientStream object and specify the pipe server, name,
138 pipe direction, options, etc.
140 pipeClient = New NamedPipeClientStream(Program.SERVER_NAME, _
141 Program.PIPE_NAME, PipeDirection.InOut, PipeOptions.None)
143 2. Connect to the named pipe by calling NamedPipeClientStream.Connect().
145 pipeClient.Connect(5000)
147 3. Set the read mode and the blocking mode of the named pipe. In this sample,
148 we set data to be read from the pipe as a stream of messages. This allows a
149 reading process to read varying-length messages precisely as sent by the
150 writing process. In this mode, you should not use StreamWriter to write the
151 pipe, or use StreamReader to read the pipe. You can read more about the
152 difference from http://go.microsoft.com/?linkid=9721786.
154 pipeClient.ReadMode = PipeTransmissionMode.Message
156 4. Send a message to the pipe server and receive its response through
157 NamedPipeClientStream.Read and NamedPipeClientStream.Write. Because
158 pipeClient.ReadMode = PipeTransmissionMode.Message, you should not use
159 StreamWriter to write the pipe, or use StreamReader to read the pipe.
162 ' Send a request from client to server.
165 Dim message As String = REQUEST_MESSAGE
166 Dim bRequest As Byte() = Encoding.Unicode.GetBytes(message)
167 Dim cbRequest As Integer = bRequest.Length
169 pipeClient.Write(bRequest, 0, cbRequest)
171 Console.WriteLine("Send {0} bytes to server: ""{1}""", _
172 cbRequest, message.TrimEnd(ControlChars.NullChar))
175 ' Receive a response from server.
179 Dim bResponse(BUFFER_SIZE - 1) As Byte
180 Dim cbResponse As Integer = bResponse.Length, cbRead As Integer
182 cbRead = pipeClient.Read(bResponse, 0, cbResponse)
184 ' Unicode-encode the received byte array and trim all the '\0'
185 ' characters at the end.
186 message = Encoding.Unicode.GetString(bResponse).TrimEnd( _
187 ControlChars.NullChar)
188 Console.WriteLine("Receive {0} bytes from server: ""{1}""", _
190 Loop While Not pipeClient.IsMessageComplete
192 5. Close the client end of the pipe by calling NamedPipeClientStream.Close().
196 -------------------------
198 B. Named pipe client by P/Invoke the native APIs related to named pipe
199 operations. (NativeNamedPipeClient.Run())
201 1. Try to connect to a named pipe by P/Invoking CreateFile and specifying the
202 target pipe server, name, desired access, etc.
204 hNamedPipe = NativeMethod.CreateFile(FULL_PIPE_NAME, _
205 FileDesiredAccess.GENERIC_READ Or _
206 FileDesiredAccess.GENERIC_WRITE, _
207 FileShareMode.Zero, Nothing, _
208 FileCreationDisposition.OPEN_EXISTING, _
211 If all pipe instances are busy, wait for 5 seconds and connect again.
213 If (Not NativeMethod.WaitNamedPipe(Program.FULL_PIPE_NAME, 5000)) Then
214 Throw New Win32Exception
217 2. Set the read mode and the blocking mode of the named pipe. In this sample,
218 we set data to be read from the pipe as a stream of messages.
220 Dim mode As PipeMode = PipeMode.PIPE_READMODE_MESSAGE
221 If (Not NativeMethod.SetNamedPipeHandleState(hNamedPipe, mode, _
222 IntPtr.Zero, IntPtr.Zero)) Then
223 Throw New Win32Exception
226 3. Send a message to the pipe server and receive its response by calling
227 the WriteFile and ReadFile functions.
230 ' Send a request from client to server.
233 Dim message As String = REQUEST_MESSAGE
234 Dim bRequest As Byte() = Encoding.Unicode.GetBytes(message)
235 Dim cbRequest As Integer = bRequest.Length, cbWritten As Integer
237 If (Not NativeMethod.WriteFile(hNamedPipe, bRequest, cbRequest, _
238 cbWritten, IntPtr.Zero)) Then
239 Throw New Win32Exception
242 Console.WriteLine("Send {0} bytes to server: ""{1}""", _
243 cbWritten, message.TrimEnd(ControlChars.NullChar))
246 ' Receive a response from server.
249 Dim finishRead As Boolean = False
251 Dim bResponse(BUFFER_SIZE - 1) As Byte
252 Dim cbResponse As Integer = bResponse.Length, cbRead As Integer
254 finishRead = NativeMethod.ReadFile(hNamedPipe, bResponse, _
255 cbResponse, cbRead, IntPtr.Zero)
258 AndAlso Marshal.GetLastWin32Error() <> ERROR_MORE_DATA) Then
259 Throw New Win32Exception
262 ' Unicode-encode the received byte array and trim all the '\0'
263 ' characters at the end.
264 message = Encoding.Unicode.GetString(bResponse).TrimEnd( _
265 ControlChars.NullChar)
266 Console.WriteLine("Receive {0} bytes from server: ""{1}""", _
269 Loop While Not finishRead ' Repeat loop if ERROR_MORE_DATA
276 /////////////////////////////////////////////////////////////////////////////
279 MSDN: System.IO.Pipes Namespace
280 http://msdn.microsoft.com/en-us/library/system.io.pipes.aspx
282 MSDN: NamedPipeClientStream
283 http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx
285 How to: Use Named Pipes to Communicate Between Processes over a Network
286 http://msdn.microsoft.com/en-us/library/bb546085.aspx
288 Introducing Pipes [Justin Van Patten]
289 http://blogs.msdn.com/bclteam/archive/2006/12/07/introducing-pipes-justin-van-patten.aspx
292 /////////////////////////////////////////////////////////////////////////////